﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Sayook.Framework.Model;

namespace Sayook.Framework.AOP.Filter.ActionFilter
{
    /// <summary>
    /// 操作筛选器
    /// <!--
    /// 实现 IActionFilter 或 IAsyncActionFilter 接口。
    /// 它们的执行围绕着操作方法的执行。
    /// -->
    /// </summary>
    public class TActionFilter : IActionFilter
    {
        private readonly ILogger<TActionFilter> _logger;
        private readonly ApiInterfaceCode _interfaceCode;

        /// <param name="name">名</param>
        public TActionFilter(ILogger<TActionFilter> logger, ApiInterfaceCode interfaceCode)
        {
            _logger = logger;
            _interfaceCode = interfaceCode;
        }

        /// <summary>
        /// Called before the action executes, after model binding is complete.
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //context.ActionArguments  - 用于读取操作方法的输入。
            var arg = context.ActionArguments;
            //context.Controller - 用于处理控制器实例。
            var controller = (ControllerBase)context.Controller;
            var key = $"{controller.ControllerContext.ActionDescriptor.ControllerName}.{controller.ControllerContext.ActionDescriptor.ActionName}";
            _logger.LogInformation(_interfaceCode.GetCode(key), "TActionFilterAttribute_OnActionExecuting");
            //context.Result - 设置 Result 会使操作方法和后续操作筛选器的执行短路。
            var result = context.Result;
        }

        /// <summary>
        /// Called after the action executes, before the action result.
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuted(ActionExecutedContext context)
        {
            //context.Canceled - 如果操作执行已被另一个筛选器设置短路，则为 true。
            //context.Exception - 如果操作或之前运行的操作筛选器引发了异常，则为非 NULL 值。
            //                    将此属性设置为 null：
            //                          有效地处理异常。
            //                          执行 Result，从操作方法中将它返回。
            if (context.Exception != null)
            {
                context.Exception = null;
                context.Result = new BadRequestObjectResult("出现异常了");
            }
        }
    }
}